package com.jar.exercise.多线程.AQS.reentrantlock.线程间通信;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 在使用Lock之前，我们使用的最多的同步方式应该是synchronized关键字来实现同步方式了。
 * 配合Object的wait()、notify()系列方法可以实现等待/通知模式。
 * Condition接口也提供了类似Object的监视器方法，与Lock配合可以实现等待/通知模式，
 * 但是这两者在使用方式以及功能特性上还是有差别的。
 * Object和Condition接口的一些对比。
 */
public class Milk {
	private ReentrantLock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();
	// 是否消费
	private boolean flag = false;
	private int num;

	public void product() {
		lock.lock();
		try {
			if (flag) {
				condition.await();
			}
			String name = Thread.currentThread().getName();
			num++;
			System.out.println("生产者：" + name + "生产" + num + "个商品");
			this.flag = true;
			condition.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void consume() {
		lock.lock();
		try {
			if (!flag) {
				condition.await();
			}
			String name = Thread.currentThread().getName();
			num--;
			System.out.println("消费者：" + name + "消费" + num + "个商品");
			this.flag = false;
			condition.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}

	}

	public static void main(String[] args) {
		Milk milk = new Milk();
		Product product = new Product(milk);
		Consume consume = new Consume(milk);
		new Thread(product).start();
		new Thread(consume).start();
	}
}
